package cn.sytton.taffe.framework.exception;

import cn.sytton.taffe.framework.constants.ExceptionMessage;
import cn.sytton.taffe.framework.response.ResponseResult;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * 全局异常处理，捕获所有springboot异常,比GlobalExceptionHandler范围更大,如404
 *
 * @author skyrock
 */
@Hidden
@Slf4j
@RestController
public class GlobalErrorHandler implements ErrorController {

    private static final String ERROR_PATH = "/error"; //出现未知错误时会走这个请求地址

    @Resource
    private ErrorAttributes errorAttributes;

    @RequestMapping(value = ERROR_PATH)
    public ResponseResult handleError(HttpServletRequest request, HttpServletResponse response) {
        int status = response.getStatus();
        switch (status) {
            case 200:
                //正常这里不会出现200，但是由于JwtAuthenticationTokenFilter提前response，这里才可能出现
                return ResponseResult.success();
            case 404:
                return ResponseResult.fail(ExceptionMessage.NOT_FOUND);
            case 401:
                return ResponseResult.fail(ExceptionMessage.UNAUTHORIZED);
            case 500:
                return ResponseResult.fail(ExceptionMessage.ERROR);
            default:
                Map<String, Object> attributesMap = getErrorAttributes(request);
                String msg = attributesMap.get("error").toString();
                return ResponseResult.fail(msg);
        }
    }

    protected Map<String, Object> getErrorAttributes(HttpServletRequest request) {
        ServletWebRequest webRequest = new ServletWebRequest(request);
        //return this.errorAttributes.getErrorAttributes(webRequest, includeStackTrace);
        return this.errorAttributes.getErrorAttributes(webRequest,
                ErrorAttributeOptions.of(ErrorAttributeOptions.Include.EXCEPTION,
                    ErrorAttributeOptions.Include.MESSAGE,
                    ErrorAttributeOptions.Include.STACK_TRACE,
                    ErrorAttributeOptions.Include.BINDING_ERRORS));
    }

}
